package com.ruoyi.async;

import java.util.concurrent.*;

public class FutureTest {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        new FutureTest().runAsync();
//        supplyAsync();
//        completableFutureTest();
    }

    public void runAsync() {
        //runAsync的使用
       CompletableFuture.runAsync(() -> {
            System.out.println("异步开始");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("异步结束");
            System.out.println("run,关注公众号:捡田螺的小男孩");
        });
        System.out.println("主进程结束");
        try {
            Thread.sleep(10000);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void supplyAsync() {
        //supplyAsync的使用
        CompletableFuture<String> supplyFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步开始");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("异步结束");
            System.out.print("supply,关注公众号:捡田螺的小男孩");
            return "捡田螺的小男孩";
        });
        System.out.println("主进程");
    }

    public static void completableTest() {
        //可以自定义线程池
        ExecutorService executor = Executors.newCachedThreadPool();
        //runAsync的使用
        CompletableFuture<Void> runFuture = CompletableFuture.runAsync(() -> {
            System.out.println("异步开始");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("异步结束");
            System.out.println("run,关注公众号:捡田螺的小男孩");
        }, executor);
        //supplyAsync的使用
        CompletableFuture<String> supplyFuture = CompletableFuture.supplyAsync(() -> {
            System.out.println("异步开始");
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("异步结束");
            System.out.print("supply,关注公众号:捡田螺的小男孩");
            return "捡田螺的小男孩";
        }, executor);
        //runAsync的future没有返回值，输出null
        System.out.println(runFuture.join());
        //supplyAsync的future，有返回值
        System.out.println(supplyFuture.join());
        executor.shutdown(); // 线程池需要关闭
    }

    public static void futureTest() throws ExecutionException, InterruptedException {
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        UserInfoService userInfoService = new UserInfoService();
        MedalService medalService = new MedalService();
        long userId = 666L;
        long startTime = System.currentTimeMillis();

        //调用用户服务获取用户基本信息
        FutureTask<UserInfo> userInfoFutureTask = new FutureTask<>(new Callable<UserInfo>() {
            @Override
            public UserInfo call() throws Exception {
                return userInfoService.getUserInfo(userId);
            }
        });
        executorService.submit(userInfoFutureTask);

        Thread.sleep(300); //模拟主线程其它操作耗时

        FutureTask<MedalInfo> medalInfoFutureTask = new FutureTask<>(new Callable<MedalInfo>() {
            @Override
            public MedalInfo call() throws Exception {
                return medalService.getMedalInfo(userId);
            }
        });
        executorService.submit(medalInfoFutureTask);

        UserInfo userInfo = userInfoFutureTask.get();//获取个人信息结果
        MedalInfo medalInfo = medalInfoFutureTask.get();//获取勋章信息结果
        System.out.println(userInfo.getId());
        System.out.println(medalInfo.getId());
        System.out.println("总共用时" + (System.currentTimeMillis() - startTime) + "ms");
    }

    public static void completableFutureTest() throws ExecutionException, InterruptedException {
        UserInfoService userInfoService = new UserInfoService();
        MedalService medalService = new MedalService();
        long userId = 666L;
        long startTime = System.currentTimeMillis();
        try {
            //调用用户服务获取用户基本信息
            CompletableFuture<UserInfo> completableUserInfoFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    return userInfoService.getUserInfo(userId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            });

            Thread.sleep(300); //模拟主线程其它操作耗时

            CompletableFuture<MedalInfo> completableMedalInfoFuture = CompletableFuture.supplyAsync(() -> {
                try {
                    return medalService.getMedalInfo(userId);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                return null;
            });

            UserInfo userInfo = completableUserInfoFuture.get(2, TimeUnit.SECONDS);//获取个人信息结果
            MedalInfo medalInfo = completableMedalInfoFuture.get();//获取勋章信息结果
        } catch (InterruptedException e) {
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("总共用时" + (System.currentTimeMillis() - startTime) + "ms");

    }
}
